package main

import (
	"fmt"
	"time"

	"github.com/gomodule/redigo/redis"
)

/**
go redis 操作string类型: 适合单个数据写入和读取
	Get: 获取key的值，返回值：错误信息error和value
	Set: 设置key和value，以及key的过期时间expiration 返回值：error
	GetSet: 设置一个key的值，并且返回这个key的旧值
	SetNX: 如果key不存在，则设置这个key的值
	MGet: 批量查询key的值
	MSet: 批量设置key的值
	Incr: 针对一个key的数值进行递增操作, 每次加1
	IncrBy: 可以指定每次递增多少
	IncrByFloat: 可以指定每次递增多少，跟IncrBy的区别是累加的是浮点数
	Decr: 针对一个key的数值进行递减操作
	DecrBy: 以指定每次递减多少
	Del: 删除单个或者多个key
	Expire: 设置key的过期时间
*/

func goRedisString(conn redis.Conn) {
	// 1. 写入
	// - Do函数[推荐]: Do(cmd string, args, ...interface{}) (interface{}, error)
	replay, err := conn.Do("set", "hello", "Golang Study Boy")
	// - Send函数; 需要配合Flush() Receive()函数使用

	// 2. 读取(因为返回的replay为interface{}类型，需要将其转换为特定类型的值; 相当于类型断言)
	// - redis.Int()
	// - redis.String()
	// - redis.Strings()
	// - resid.Bytes()
	// - redis.ByteSlices()
	// - redis.Values()
	// - redis.Bool()
	r1, e1 := redis.String(replay, err)
	fmt.Println("r1, e1:", r1, e1)
	// 获取指定的key值
	r2, e2 := redis.String(conn.Do("get", "hello"))
	fmt.Println("r2, e2:", r2, e2)
	// 清除指定的key
	conn.Do("del", "hello")
	r3, e3 := redis.String(conn.Do("get", "hello"))
	fmt.Println("r3, e3:", r3, e3)

	// 3. 设置key的过期时间
	_, gq_err := conn.Do("set", "gq_test", "10s后过期")
	if gq_err != nil {
		fmt.Println("set error:", gq_err)
		return
	}
	_, expire_error := conn.Do("expire", "gq_test", 10*time.Second)
	if expire_error != nil {
		fmt.Println("set error:", expire_error)
		return
	}

	// 4. Incr系列
	_, err1 := conn.Do("set", "incr_count", 20)
	if err1 != nil {
		fmt.Println("incr set error:", err1)
	}
	val, err2 := conn.Do("INCR", "incr_count")
	if err2 != nil {
		fmt.Println("incr error:", err2)
	}
	fmt.Printf("incr val:%s, %T\n", val, val)
	incrVal1, _ := redis.Int(conn.Do("get", "incr_count"))
	fmt.Println("incr value1:", incrVal1) // 21
	incrVal2, _ := redis.Int(conn.Do("get", "incr_count"))
	fmt.Println("incr value2:", incrVal2) // 22
	incrVal3, _ := redis.Int(conn.Do("get", "incr_count"))
	fmt.Println("incr value3:", incrVal3) // 23

	// 5. del
	_, err3 := conn.Do("del", "incr_count")
	if err3 != nil {
		fmt.Println("del error:", err3)
	}
}
